package com.sytc.camera.usb;


import com.sytc.camera.dllinterface.CyFX3Device;
import com.sytc.camera.dllinterface.FX3_FWDWNLOAD_ERROR_CODE;
import com.sytc.camera.dllinterface.FX3_FWDWNLOAD_MEDIA_TYPE;
import com.sytc.camera.dllinterface.TransferResult;
import com.sytc.camera.uicontroller.MainuiController;
import com.sytc.camera.util.AppConfig;
import com.sytc.camera.util.MyRuntimeException;
import com.sytc.camera.util.RUN_STATE;
import com.sytc.camera.util.Util;
import javafx.application.Platform;
import javafx.scene.image.Image;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import static java.lang.Thread.sleep;

/**
 * 订阅者和发布者
 */
@Component
public class OperateUsb {

    private static final Logger log = LoggerFactory.getLogger(OperateUsb.class);


    private FileOutputStream fos;
    private String outputFilename;
    private AppConfig appConfig;
    @Autowired
    private CyFX3Device device;
    private MainuiController mainuiController;
    private int oneByteImageSize;
    private int twoBytesImageSize;
    private int oneByteImagePacketSize;
    private int twoBytesImagePacketSize;
    private int tailLen;
    private int packetOtherDataSize;

    // 队列，用来存储数据包
    private final BlockingQueue<byte[]> packetQueue;
    private final BlockingQueue<byte[]> imagePacketQueue;
    private final BlockingQueue<Image> imageQueue;
    private AtomicBoolean usbRunning;
    private AtomicInteger fileState; // 0:停止，1:运行，2:暂停
    private AtomicBoolean readFileFinish;
    private final ThreadPoolExecutor operateImagePool;
    private Thread runFileTread;
    private double newFileProgress = 0;
    private double oldFileProcess = 0;

    @Autowired
    private OperateUsb(AppConfig appConfig) {
        this.appConfig = appConfig;
        this.operateImagePool = new ThreadPoolExecutor(
                2,  // 核心线程数
                10, // 最大线程数
                30, // 空闲线程的存活时间
                TimeUnit.SECONDS, // 空闲时间的单位
                new ArrayBlockingQueue<>(100), // 有界队列，任务排队，如果队列满了会拒绝任务
                new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略：当前线程执行任务，防止任务丢失
        );
        this.oneByteImageSize = appConfig.getImageHeight() * appConfig.getImageWidth();
        this.twoBytesImageSize = this.oneByteImageSize * 2;
        this.packetOtherDataSize = appConfig.getImagePacketHead().length + appConfig.getFrontRemainSize() + appConfig.getBackRemainSize() + appConfig.getImagePacketTail().length;
        this.oneByteImagePacketSize = this.oneByteImageSize + this.packetOtherDataSize;
        this.twoBytesImagePacketSize = this.twoBytesImageSize + this.packetOtherDataSize;
        this.tailLen = appConfig.getImagePacketTail().length;
        this.packetQueue = new ArrayBlockingQueue<>(appConfig.getQueueSize());
        this.imagePacketQueue = new ArrayBlockingQueue<>(appConfig.getQueueSize());
        this.imageQueue = new ArrayBlockingQueue<>(appConfig.getQueueSize());
        this.usbRunning = new AtomicBoolean(false);
        this.fileState = new AtomicInteger(0);
        this.readFileFinish = new AtomicBoolean(false);

    }

    public double getOldFileProcess() {
        return oldFileProcess;
    }

    public void setOldFileProcess(double oldFileProcess) {
        this.oldFileProcess = oldFileProcess;
    }

    public double getNewFileProgress() {
        return newFileProgress;
    }

    public void setNewFileProgress(double newFileProgress) {
        this.newFileProgress = newFileProgress;
    }

    public Thread getRunFileTread() {
        return runFileTread;
    }

    public void setRunFileTread(Thread runFileTread) {
        this.runFileTread = runFileTread;
    }

    public MainuiController getMainuiController() {
        return mainuiController;
    }

    public void setMainuiController(MainuiController mainuiController) {
        this.mainuiController = mainuiController;
    }

    public BlockingQueue<Image> getImageQueue() {
        return imageQueue;
    }

    public boolean getUsbRunning() {
        return usbRunning.get();
    }

    // 设置状态
    public void setUsbRunning(boolean value) {
        usbRunning.set(value);
    }

    // 获取当前状态（线程安全）
    public RUN_STATE getFileState() {
        return RUN_STATE.fromInt(fileState.get());
    }

    // 设置当前状态（线程安全）
    public void setFileState(RUN_STATE fileState) {
        this.fileState.set(fileState.getValue());
    }


    public boolean getReadFileFinish() {
        return readFileFinish.get();
    }

    public void setReadFileFinish(boolean value) {
        this.readFileFinish.set(value);
    }

    public String getOutputFilename() {
        return outputFilename;
    }

    public void setOutputFilename(String outputFilename) {
        this.outputFilename = outputFilename;
    }

    public void closeFile() {
        if(null == fos) return;
        try {
            fos.close();
            fos = null;
            log.info("成功关闭文件:"+outputFilename);

            // 如果文件长度为0，删除文件
            File file = new File(outputFilename);
            if (file.exists() && file.length() == 0) {
                file.delete();  // 删除文件
            }
        } catch (IOException e) {
            log.error("关闭文件失败:" + outputFilename);
        }
    }

    public void createNewFile() {
        if(null != fos){
            closeFile();
        }
        outputFilename = System.getProperty("user.dir") + appConfig.getOutPath() + "file"+Util.getMsTimestamp()+".dat";
        try {
            fos = new FileOutputStream(outputFilename);
            log.info("成功打开文件:"+outputFilename);
        } catch (FileNotFoundException e) {
            log.error("打开文件失败:"+outputFilename);
        }
    }

    public List<String> getDevices() {
        // 创建设备对象
        if (null == device) {
            throw new MyRuntimeException("获取操作句柄失败");
        }
        log.info("获得操作句柄:" + device);

        // 获取设备数量
        if (0 == device.deviceCount()) {
            throw new MyRuntimeException("设备数为0");
        }
        log.info("设备数为：" + device.deviceCount());

        // 创建返回结果列表
        List<String> deviceList = new ArrayList<>();
        String deviceName;

        // 遍历设备加载固件
        for (int i = 0; i < device.deviceCount(); i++) {
            // 打开设备
            if (device.open(i)) {
                downloadFw(i);
                device.close();
            }
        }

        // 等待固件加载完成
        try {
            sleep(1000);
        } catch (InterruptedException e) {

        }

        // 遍历设备输出设备名称
        for (int i = 0; i < device.deviceCount(); i++) {
            // 打开设备
            if (device.open(i)) {
                deviceList.add(device.getDeviceName());
                device.close();
            }else{
                deviceList.add("设备"+i+"无法打开");
            }
        }

        // 返回设备信息列表
        return deviceList;
    }

    public void downloadFw(int deviceIndex){

        if("FX3".equals(device.getDeviceName())){
            log.info("不需要加载固件");
            return;
        }

        if (!device.isBootLoaderRunning()) {
            throw new MyRuntimeException("无法加载固件：BootLoader is not Running");
        }

        String absolutePath = Util.getAbsolutePath(appConfig.getFirmwarePath());
        if (null == absolutePath) {
            throw new MyRuntimeException("文件未找到: " + absolutePath);
        }

        FX3_FWDWNLOAD_ERROR_CODE result = device.downloadFw(absolutePath, FX3_FWDWNLOAD_MEDIA_TYPE.RAM);
        if (FX3_FWDWNLOAD_ERROR_CODE.SUCCESS != result) {
            throw new MyRuntimeException("固件加载失败");
        }
        log.info("固件加载成功");

    }



    public void open(int deviceIndex) {
        if(!device.open(deviceIndex)) {
            throw new MyRuntimeException("打开设备失败");
        }
        log.info("已打开设备"+deviceIndex+" "+device.getDeviceName());
    }

    public Object getDeviceName() {
        return device.getDeviceName();
    }

    public void closeDevice() {
        // 关闭设备
        device.close();
        log.info("关闭设备");
    }

    public void deleteOject() {
        device.delete();
        log.info("删除句柄");
    }

    // 将 RAW 数据转换为 JavaFX 图像
    private Image createImageFromRawData(byte[] data) {

        WritableImage image = new WritableImage(appConfig.getImageWidth(), appConfig.getImageHeight());
        PixelWriter pixelWriter = image.getPixelWriter();

        // 如果是单通道：一个像素一个字节
        if(data.length == this.oneByteImagePacketSize){
            log.debug("单通道image");
            for (int i = 0; i < oneByteImageSize; i++) {
                int pixelValue = data[appConfig.getFrontRemainSize() + i] & 0xFF;  // 这是imagepacket包，前面有一段预留字节
                pixelWriter.setColor(i / appConfig.getImageWidth(), i % appConfig.getImageWidth(), Color.rgb(pixelValue, pixelValue, pixelValue));
            }
        }
        // 如果是双通道：一个像素两个字节，只保留低字节
        else if(data.length == this.twoBytesImagePacketSize) {
            log.debug("双通道image");
            for (int i = 0; i < oneByteImageSize; i++) {
                int pixelValue = data[appConfig.getFrontRemainSize() + i * 2 + 1] & 0xFF;
                pixelWriter.setColor(i / appConfig.getImageWidth(), i % appConfig.getImageWidth(), Color.rgb(pixelValue, pixelValue, pixelValue));
            }

        }
        // 其它的包有问题，需要丢弃
        else{
            throw new MyRuntimeException("imagePacket 长度不匹配，不是单通道，也不是双通道，所以丢弃不处理, 长度为：" + data.length);
        }

        // 创建一个包含图像像素数据的 JavaFX 图像
        return image;
    }

    public void usbBeginOperateImage() {

        log.info("即将开始处理image包到image图像");

        new Thread(() -> {
            try {
                while (getUsbRunning()) {
                    byte[] imageData = imagePacketQueue.take(); // 阻塞，直到队列有数据
                    // 提交到线程池进行处理
                    operateImagePool.submit(() -> {
                        try {
                            if(imageQueue.size() >= appConfig.getQueueSize()){
                                imageQueue.take();
                                log.error("丢弃一个imagePacket包");
                            }
                            imageQueue.put(createImageFromRawData(imageData));
                        } catch (Exception e) {
                            log.error(e.getMessage());
                        }
                    });
                }
            } catch (Exception e) {
                log.error("处理imagePacket异常：" + e.getMessage());
            }
        }).start();

    }

    public void fileBeginOperateImage() {

        log.info("即将开始处理image包到image图像");

        new Thread(() -> {
            try {
                while (RUN_STATE.STOPPED != getFileState()) {
                    byte[] imageData = imagePacketQueue.take(); // 阻塞，直到队列有数据
                    // 提交到线程池进行处理
                    operateImagePool.submit(() -> {
                        try {
                            if(imageQueue.size() >= appConfig.getQueueSize()){
                                imageQueue.take();
                                log.error("丢弃一个imagePacket包");
                            }
                            imageQueue.put(createImageFromRawData(imageData));
                        } catch (Exception e) {
                            log.error(e.getMessage());
                        }
                    });
                }
            } catch (Exception e) {
                log.error("处理imagePacket异常：" + e.getMessage());
            }
        }).start();

    }


    public void usbBeginDividePackage() {

        log.info("即将开始拆分usb数据包到image包");

        new Thread(() -> {
            try {

                byte[] remainData = new byte[0];
                int remainHeadIndex = -1;
                int headIndex = -1;
                int tailIndex = -1;

                while (getUsbRunning()) {

                    // 获取新包
                    byte[] packet = packetQueue.take();

                    // 如果前边有剩包
                    if(remainHeadIndex >= 0){
                        // 按单通道找数据，因为我发现有时候是单通道
                        tailIndex = Util.indexOf(packet, appConfig.getImagePacketTail(), this.oneByteImagePacketSize - (remainData.length - remainHeadIndex) - tailLen);
                        if (tailIndex >= 0) {

                            // 处理数据
                            byte[] imagePacket = new byte[remainData.length - remainHeadIndex + tailIndex + tailLen];
                            System.arraycopy(remainData, remainHeadIndex, imagePacket, 0, remainData.length-remainHeadIndex);
                            System.arraycopy(packet, 0, imagePacket, remainData.length-remainHeadIndex, tailIndex + 4);

                            // 加入队列
                            if (imagePacketQueue.size() >= appConfig.getQueueSize()) {
                                imagePacketQueue.take();  // 移除最前面的元素
                                log.error("丢弃一个image包");
                            }
                            imagePacketQueue.put(imagePacket); // 向队列添加新的元素
                            log.debug(" 放入一个imagePacket包 "+" remainHeadIndex "+remainHeadIndex+" tailIndex "+tailIndex);
                        }else{
                            log.error("丢弃一个usb包，因为上个包有开始标记，这个包没有结束标记");
                            continue; // 如果没有找到尾部，则继续找，直到找到
                        }
                    }

                    while((headIndex = Util.indexOf(packet, appConfig.getImagePacketHead(), tailIndex)) >= 0){
                        tailIndex = Util.indexOf(packet, appConfig.getImagePacketTail(), headIndex + oneByteImageSize);
                        if(tailIndex >= 0){
                            if (imagePacketQueue.size() >= appConfig.getQueueSize()) {
                                imagePacketQueue.take();  // 移除最前面的元素
                                log.error("丢弃一个image包");
                            }
                            imagePacketQueue.put(Arrays.copyOfRange(packet, headIndex, tailIndex+ tailLen) ); // 向队列添加新的元素
                            log.debug(" 放入一个imagePacket包 "+" headIndex "+headIndex+" tailIndex "+tailIndex);
                        }else{
                            break;
                        }
                    }

                    remainData = packet;
                    remainHeadIndex = headIndex;
                }
            } catch (InterruptedException e) {
                log.error(e.getMessage());
            }
        }).start();
    }

    public void fileBeginDividePackage() {

        log.info("即将开始拆分usb数据包到image包");

        new Thread(() -> {
            try {

                byte[] remainData = new byte[0];
                int remainHeadIndex = -1;
                int headIndex = -1;
                int tailIndex = -1;

                while (RUN_STATE.STOPPED != getFileState()) {

                    // 获取新包
                    byte[] packet = packetQueue.take();

                    // 如果前边有剩包
                    if(remainHeadIndex >= 0){
                        // 按单通道找数据，因为我发现有时候是单通道
                        tailIndex = Util.indexOf(packet, appConfig.getImagePacketTail(), this.oneByteImagePacketSize - (remainData.length - remainHeadIndex) - tailLen);
                        if (tailIndex >= 0) {

                            // 处理数据
                            byte[] imagePacket = new byte[remainData.length - remainHeadIndex + tailIndex + tailLen];
                            System.arraycopy(remainData, remainHeadIndex, imagePacket, 0, remainData.length-remainHeadIndex);
                            System.arraycopy(packet, 0, imagePacket, remainData.length-remainHeadIndex, tailIndex + 4);

                            // 加入队列
                            if (imagePacketQueue.size() >= appConfig.getQueueSize()) {
                                imagePacketQueue.take();  // 移除最前面的元素
                                log.error("丢弃一个image包");
                            }
                            imagePacketQueue.put(imagePacket); // 向队列添加新的元素
                            log.debug(" 放入一个imagePacket包 "+" remainHeadIndex "+remainHeadIndex+" tailIndex "+tailIndex);
                        }else{
                            log.error("丢弃一个usb包，因为上个包有开始标记，这个包没有结束标记");
                            continue; // 如果没有找到尾部，则继续找，直到找到
                        }
                    }

                    while((headIndex = Util.indexOf(packet, appConfig.getImagePacketHead(), tailIndex)) >= 0){
                        tailIndex = Util.indexOf(packet, appConfig.getImagePacketTail(), headIndex + oneByteImageSize);
                        if(tailIndex >= 0){
                            if (imagePacketQueue.size() >= appConfig.getQueueSize()) {
                                imagePacketQueue.take();  // 移除最前面的元素
                                log.error("丢弃一个image包");
                            }
                            imagePacketQueue.put(Arrays.copyOfRange(packet, headIndex, tailIndex+ tailLen) ); // 向队列添加新的元素
                            log.debug(" 放入一个imagePacket包 "+" headIndex "+headIndex+" tailIndex "+tailIndex);
                        }else{
                            break;
                        }
                    }

                    remainData = packet;
                    remainHeadIndex = headIndex;
                }
            } catch (InterruptedException e) {
                log.error(e.getMessage());
            }
        }).start();
    }


    public void usbBeginGetData() {

        log.info("即将开始接收usb数据包");

        new Thread(() -> {

            while (getUsbRunning()) {
                try {

                    byte[] packet = new byte[appConfig.getTransferSize()];  // 接收缓冲区大小
                    TransferResult result = device.inXferData(packet);
                    log.debug("接收到的数据包长度: " + result.getActualLength());

                    if (0 != result.getActualLength()) {
                        // 判断队列是否已满
                        if (packetQueue.size() >= 100) {
                            packetQueue.take();  // 移除最前面的元素
                            log.error("丢弃一个usb数据包" + packet.length);
                        }
                        packetQueue.put(packet); // 向队列添加新的元素
                        if(null != fos) {
                            fos.write(packet);  // 写入文件
                        }
                    }

                } catch (Exception e) {
                    log.error(e.getMessage());
                }

            }
        }).start();

    }

    public void fileRrecordIndex(String filePath){

        new Thread(() -> {


            try (RandomAccessFile bis = new RandomAccessFile(filePath, "r");
                    BufferedWriter writer = new BufferedWriter(new FileWriter(filePath+"-index.txt"))
            ) {

                long fileLength = new File(filePath).length();
                writer.write("fileLength:"+fileLength);
                byte[] packet = new byte[appConfig.getTransferSize()];  // 接收缓冲区大小
                int bytesRead;
                long currentPosition = 0;
                int headIndex = -1;
                int tailIndex = -1;
                long currentHeadIndex = -1;
                long currentTailIndex = -1;
                int imagePacketNum = 0;

                // 逐步扫描文件
                while ((bytesRead = bis.read(packet)) != -1) {



                    headIndex = Util.indexOf(packet,  appConfig.getImagePacketHead(), 0, bytesRead);
                    // 没找到头，直接下一个循环
                    if(-1 == headIndex){
                        // 更新当前位置,为了避免头字节被拆分，所以留几个字节
                        currentPosition += (bytesRead-4);
                        bis.seek(currentPosition);
                        continue;
                    }

                    // 打印头地址
                    currentHeadIndex = currentPosition + headIndex;
                    writer.write("\n第" + (++imagePacketNum) + "个image包\theadIndex:" + currentHeadIndex);

                    // 直到找到尾为止
                    int fromIndex = headIndex;
                    while(-1 == (tailIndex = Util.indexOf(packet, appConfig.getImagePacketTail(), fromIndex, bytesRead))){
                        // 如果到文件尾了,任务结束
                        if(currentPosition + bytesRead >= fileLength){
                            writer.write("\n[end]\tfileLength:"+fileLength);
                            return;
                        }

                        currentPosition += (bytesRead-4);
                        bis.seek(currentPosition);
                        bytesRead = bis.read(packet);
                        fromIndex = 0;
                    }
                    // 打印尾地址
                    currentTailIndex = currentPosition + tailIndex;
                    writer.write("\ttailIndex:" + currentTailIndex + "\tlength:"+(currentTailIndex-currentHeadIndex+appConfig.getImagePacketTail().length));
                    currentPosition += tailIndex;
                    bis.seek(currentPosition);
                }
            } catch (Exception e) {
                log.error("记录头尾索引失败："+e.getMessage());
            }
        }).start();

    }

    public void fileBeginGetData(String filePath) {


        log.info("即将开始读取文件数据");

        new Thread(() -> {

            try(FileInputStream fis = new FileInputStream(filePath)) {

                // 持续读取直到文件结束
                while (RUN_STATE.STOPPED != getFileState()) {

                    byte[] packet = new byte[appConfig.getTransferSize()];  // 接收缓冲区大小
                    int bytesRead = fis.read(packet);

                    log.debug("读取到的数据长度:: " + bytesRead);

                    if (-1 != bytesRead) {
                        // 判断队列是否已满
                        if (packetQueue.size() >= 100) {
                            packetQueue.take();  // 移除最前面的元素
                            log.error("丢弃一个文件数据包" + packet.length);
                        }
                        packetQueue.put(packet); // 向队列添加新的元素
                    }else{
                        setReadFileFinish(true);
                        break;
                    }
                }

            } catch (Exception e) {
                log.error(e.getMessage());
            }

        }).start();

    }


    public void closePool() {
        operateImagePool.shutdown();
        log.info("关闭线程池");
    }

    public void fileShowImage() {
        // 展示image
        new Thread(() -> {
            while(RUN_STATE.STOPPED != getFileState()){
                try {
                    // 如果文件获取结束了，也展示结束了，就停止
                    if(getReadFileFinish() && (0 == imageQueue.size())){
                        Platform.runLater(() -> {
                            // 更新 UI
                            mainuiController.onRunFile(null);
                        });
                        break;
                    }
                    Image image = imageQueue.take();
                    log.debug("------------------显示图像------------");

                    Platform.runLater(() -> {
                        // 更新 UI
                        mainuiController.mainImage.setImage(image);
                    });

                    // 播放速度
                    sleep(10*(100 - (int)mainuiController.speedSlider.getValue()));

                } catch (InterruptedException e) {
                    log.error("获取并显示image失败:"+e.getMessage());
                }
            }
        }).start();
    }


    public void usbShowImage() {
        // 展示image
        new Thread(() -> {
            while(getUsbRunning()){
                try {
                    // 如果文件获取结束了，也展示结束了，就停止
                    if(getReadFileFinish() && (0 == imageQueue.size())){
                        Platform.runLater(() -> {
                            // 更新 UI
                            mainuiController.onRunFile(null);
                        });
                        break;
                    }
                    Image image = imageQueue.take();
                    log.debug("------------------显示图像------------");

                    Platform.runLater(() -> {
                        // 更新 UI
                        mainuiController.mainImage.setImage(image);
                    });

                    // 播放速度
                    sleep(10*(100 - (int)mainuiController.speedSlider.getValue()));

                } catch (InterruptedException e) {
                    log.error("获取并显示image失败:"+e.getMessage());
                }
            }
        }).start();
    }

    public void fileBeginAll(String filePath) {


        runFileTread = new Thread(() -> {

            fileRunAll(filePath);

            if(RUN_STATE.STOPPED != getFileState()){
                Platform.runLater(() -> {
                    mainuiController.onRunFile(null);
                });
            }

        });

        runFileTread.start();



    }

    private void fileRunAll(String filePath) {
        try (RandomAccessFile bis = new RandomAccessFile(filePath, "r");
             BufferedWriter writer = new BufferedWriter(new FileWriter(filePath +"-index.txt"))
        ) {

            long fileLength = new File(filePath).length();
            writer.write("fileLength:"+fileLength);
            byte[] usbPacket = new byte[oneByteImagePacketSize];  // 接收缓冲区大小
            int bytesRead;
            long[] currentPosition = {0};
            int headIndex = -1;
            int tailIndex = -1;
            long currentHeadIndex = -1;
            long currentTailIndex = -1;

            // 逐步扫描文件
            while (((bytesRead = fileRead(bis, usbPacket, fileLength, currentPosition)) != -1) && ( RUN_STATE.STOPPED != getFileState())) {

                try {

                    headIndex = Util.indexOf(usbPacket, appConfig.getImagePacketHead(), 0, bytesRead);
                    // 没找到头，直接下一个循环
                    if (-1 == headIndex) {
                        // 更新当前位置,为了避免头字节被拆分，所以留几个字节
                        currentPosition[0] += (bytesRead - 4);
                        bis.seek(currentPosition[0]);
                        continue;
                    }

                    // 打印头地址
                    currentHeadIndex = currentPosition[0] + headIndex;
                    writer.write("\nheadIndex:" + currentHeadIndex);

                    // 直到找到尾为止
                    int fromIndex = headIndex;
                    while (-1 == (tailIndex = Util.indexOf(usbPacket, appConfig.getImagePacketTail(), fromIndex, bytesRead))) {
                        // 如果到文件尾了,任务结束
                        if (currentPosition[0] + bytesRead >= fileLength) {
                            writer.write("\n[end]\tfileLength:" + fileLength);
                            return;
                        }

                        currentPosition[0] += (bytesRead - 4);
                        bis.seek(currentPosition[0]);
                        bytesRead = fileRead(bis, usbPacket, fileLength, currentPosition);
                        fromIndex = 0;
                    }
                    // 打印尾地址
                    currentTailIndex = currentPosition[0] + tailIndex;
                    int imagePacketlen = (int) (currentTailIndex - currentHeadIndex + appConfig.getImagePacketTail().length);
                    writer.write("\ttailIndex:" + currentTailIndex + "\tlength:" + imagePacketlen);

                    // 生成image
                    byte[] imageData = new byte[imagePacketlen];
                    bis.seek(currentHeadIndex);
                    bis.read(imageData);
                    currentPosition[0] = bis.getFilePointer();

                    // 提交到线程池进行处理
                    operateImagePool.submit(() -> {
                        try {
                            Image image = createImageFromRawData(imageData);// 这一句不能放到Platform里，会占用ui时间，让ui阻塞
                            Platform.runLater(() -> {
                                mainuiController.mainImage.setImage(image);
                            });
                        } catch (Exception e) {
                            log.error(e.getMessage());
                        }
                    });


                }catch (Exception e){
                    log.error("播放文件遇到问题："+e.getMessage());
                }

                // 如果是暂停状态，就一直待命在这里
                while(RUN_STATE.PAUSED == getFileState());
            }
        } catch (Exception e) {
            log.error("记录头尾索引失败："+e.getMessage());
        }
    }

    private int fileRead(RandomAccessFile bis, byte[] imageData, long fileLength, long[] currentPosition) throws IOException {

        if(oldFileProcess != newFileProgress){
            oldFileProcess = newFileProgress;
            currentPosition[0] = (int)(fileLength*oldFileProcess);
            bis.seek(currentPosition[0]);
        }

        try {
            // 放到每次读取这里是为了让进度条更平滑
            sleep((int)(appConfig.getMaxPauseMilliSec() * (1 - mainuiController.speedSlider.getValue())));
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        }

        int bytesRead = bis.read(imageData);

        double process = (double)bis.getFilePointer()/fileLength;
        Platform.runLater(() -> {
            // 更新 UI
            mainuiController.fileProcessBar.setProgress(process);
        });
        return bytesRead;
    }

}
